﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace JqlEditor
{
    internal class JqlChessmanCollection
    {
        private JqlChessman[,] ChessmanList = new JqlChessman[JqlConsts.LayoutRowCount, JqlConsts.LayoutColCount];

        public JqlChessman this[int row, int col]
        {
            get
            {
                return ChessmanList[row, col];
            }
            set
            {
                if (ChessmanList[row, col] != value)
                {
                    ChessmanList[row, col] = value;
                }
            }
        }

        private void InitializeChessmanList(byte[] layoutBytes)
        {
            for (int i = 0; i < ChessmanList.GetLength(0); i++)
            {
                for (int j = 0; j < ChessmanList.GetLength(1); j++)
                {
                    ChessmanList[i, j] = new JqlChessman
                    {
                        ChessmanType = (ChessmanType)layoutBytes[i * JqlConsts.LayoutColCount + j]
                    };

                    if (CheckPosition(i, j) == SpecialPosition.Bunker)
                    {
                        ChessmanList[i, j].Visible = false;
                    }
                }
            }
        }
        public bool Swap(Point p1, Point p2)
        {
            return Swap(p1.Y, p1.X, p2.Y, p2.X);
        }
        public bool Swap(int row1, int col1, int row2, int col2)
        {
            if (!IsValidPosition(row1, col1) || !IsValidPosition(row2, col2)) return false;
            if (!CanSwap(row1, col1, row2, col2)) return false;
            
            JqlChessman temp = this[row1, col1].Clone();
            this[row1, col1] = this[row2, col2];
            this[row2, col2] = temp;

            return true;
        }
        private static bool IsValidPosition(int row, int col)
        {
            if (row < 0 || row >= JqlConsts.LayoutRowCount) return false;
            if (col < 0 || col >= JqlConsts.LayoutColCount) return false;
            return true;
        }
        private bool CanSwap(int row1, int col1, int row2, int col2)
        {
            SpecialPosition position1 = CheckPosition(row1, col1);
            SpecialPosition position2 = CheckPosition(row2, col2);

            // 棋子不能放行营里
            if (position1 == SpecialPosition.Bunker || position2 == SpecialPosition.Bunker)
            {
                return false;
            }

            // 炸弹不能摆第一排
            if (position1 == SpecialPosition.FirstRow && this[row2, col2].ChessmanType == ChessmanType.Bomb)
            {
                return false;
            }
            if (position2 == SpecialPosition.FirstRow && this[row1, col1].ChessmanType == ChessmanType.Bomb)
            {
                return false;
            }

            // 地雷不能放前四排
            if (position1 == SpecialPosition.LastTwoRows && (position2 != SpecialPosition.LastTwoRows && position2 != SpecialPosition.Base))
            {
                if (this[row1, col1].ChessmanType == ChessmanType.Mine)
                {
                    return false;
                }
            }
            if ((position1 != SpecialPosition.LastTwoRows && position1 != SpecialPosition.Base) && position2 == SpecialPosition.LastTwoRows)
            {
                if (this[row2, col2].ChessmanType == ChessmanType.Mine)
                {
                    return false;
                }
            }

            // 军旗只能在大本营
            if (this[row1, col1].ChessmanType == ChessmanType.Flag && position2 != SpecialPosition.Base)
            {
                return false;
            }
            if (this[row2, col2].ChessmanType == ChessmanType.Flag && position1 != SpecialPosition.Base)
            {
                return false;
            }

            return true;
        }
        internal static SpecialPosition CheckPosition(int row, int col)
        {
            if (!IsValidPosition(row, col)) return SpecialPosition.None;
            // 判断是不是第一排
            if (row == 0) return SpecialPosition.FirstRow;
            // 判断是不是大本营
            if (row == JqlConsts.LayoutRowCount - 1 && (col == 1 || col == 3)) return SpecialPosition.Base;
            // 判断是不是最后两排
            if (row == JqlConsts.LayoutRowCount - 2 || row == JqlConsts.LayoutRowCount - 1) return SpecialPosition.LastTwoRows;
            // 判断是不是行营
            if (row > 0 && row < JqlConsts.LayoutColCount && col > 0 && col < JqlConsts.LayoutColCount)
            {
                if (row == col || row + col == 4)
                {
                    return SpecialPosition.Bunker;
                }
            }
            // 以上都不是，那就是非特殊位置
            return SpecialPosition.NonSpecial;
        }
        public byte[] ToBytes()
        {
            byte[] bytes = new byte[JqlConsts.JqlFileLayoutLength];
            for (int i = 0; i < bytes.Length; i++)
            {
                bytes[i] = (byte)ChessmanList[i / JqlConsts.LayoutColCount, i % JqlConsts.LayoutColCount].ChessmanType;
            }
            return bytes;
        }
        public void Flip()
        {
            for (int r = 0; r < JqlConsts.LayoutRowCount; r++)
            {
                for (int c1 = 0, c2 = JqlConsts.LayoutColCount - 1; c1 < c2; c1++, c2--)
                {
                    JqlChessman temp = ChessmanList[r, c1];
                    ChessmanList[r, c1] = ChessmanList[r, c2];
                    ChessmanList[r, c2] = temp;
                }
            }
        }

        public JqlChessmanCollection(JqlInfo jqlInfo)
        {
            InitializeChessmanList(jqlInfo.LayoutBytes);
        }
    }
}
